#!/usr/bin/env php
<?php
/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

require_once 'app/init.php';
require_once APPPATH.'/../tests/Test.php';
require_once APPPATH.'/../tests/AirHttpTest.php';

// init
AIR2_DBManager::init();
$browser = new AirHttpTest();
$browser->set_test_user();
$csv_dir = dirname(__FILE__).'/csv';

// helper function for POSTing a file
function upload_file($url, $fld_name, $file) {
    global $browser;

    $session = curl_init($browser->base_url.$url);
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($session, CURLOPT_POST, true);
    curl_setopt($session, CURLOPT_POSTFIELDS, array($fld_name => "@$file"));
    foreach ($browser->cookies as $nm => $ck) {
        curl_setopt($session, CURLOPT_COOKIE, "$nm=$ck");
    }
    curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($session, CURLOPT_SSL_VERIFYHOST, false);

    return curl_exec($session);
}


plan(51);
$test_uuids = array();

/**********************
 * Test uploading files.  NOTE: this must be done using CURL, since
 * SimpleBrowser doesn't support POSTing files.
 */
$resp = upload_file('upload.json', 'csvfile', "$csv_dir/test_valid.csv");
ok( $resp, 'upload valid' );
ok( $json = json_decode($resp, true), 'upload valid - decode' );
ok( isset($json['success']) && $json['success'], 'upload valid - success' );
ok( isset($json['radix']['tank_uuid']), 'upload valid - uuid' );
is( $json['radix']['tank_type'], 'C', 'upload valid - csv type' );
if (isset($json['radix']['tank_uuid'])) $test_uuids[] = $json['radix']['tank_uuid'];

// upload a file with a bad type (non-csv)
$img_path = AIR2_DOCROOT.'/css/img/icons/address-book-blue.png';
$resp = upload_file('upload.json', 'csvfile', $img_path);
ok( $resp, 'upload bad type' );
ok( $json = json_decode($resp, true), 'upload bad type - decode' );
// TODO: how to check MIME Type on server side?
ok( isset($json['success']) && !$json['success'], 'upload bad type - unsuccess' );
ok( !isset($json['radix']), 'upload bad type - no radix' );

// upload the wrong fieldname
$resp = upload_file('upload.json', 'fake', "$csv_dir/test_valid.csv");
ok( $resp, 'upload wrong field' );
ok( $json = json_decode($resp, true), 'upload wrong field - decode' );
ok( isset($json['success']) && !$json['success'], 'upload wrong field - unsuccess' );
ok( !isset($json['radix']), 'upload wrong field - no radix' );

// check the resp codes using SimpleBrowser
$browser->set_content_type(AirHttpTest::$HTML);
ok( $resp = $browser->http_post("upload"), 'html POST uploads' );
is( $browser->resp_code(), 200, 'html POST uploads - resp 200' );
ok( !json_decode($resp, true), 'html POST uploads - not json' );
ok( $resp = $browser->http_get("upload"), 'html GET uploads' );
is( $browser->resp_code(), 200, 'html GET uploads - resp 200' );
$browser->set_content_type(AirHttpTest::$JSON);
ok( $resp = $browser->http_post("upload"), 'json POST uploads' );
is( $browser->resp_code(), 200, 'json POST uploads - resp 200' );
ok( $json = json_decode($resp, true), 'json POST uploads - json decode' );
ok( $resp = $browser->http_get("upload"), 'json GET uploads' );
is( $browser->resp_code(), 200, 'json GET uploads - resp 200' );


/**********************
 * CSV parsing preview testing
 */
$uuid = $test_uuids[0];
ok( $resp = $browser->http_get("upload/$uuid"), 'preview valid get' );
ok( $resp = $browser->http_get("upload/$uuid/preview", array('d'=>';','e'=>'"')), 'preview params' );
ok( $json = json_decode($resp, true), 'preview params json' );
ok( isset($json['success']), 'preview params success' );
ok( isset($json['size']), 'preview params size' );
ok( isset($json['lines']), 'preview params lines' );
ok( isset($json['header']), 'preview params header' );
ok( isset($json['preview']), 'preview params preview' );

// mappings fail
foreach ($json['header'] as $idx => $hdr) {
    is( $hdr['valid'], false, "preview params invalid header $idx" );
}


/**********************
 * Upload a valid header'd csv
 */
$resp = upload_file('upload.json', 'csvfile', "$csv_dir/test_header.csv");
ok( $resp, 'upload header' );
ok( $json = json_decode($resp, true), 'upload header - decode' );
ok( isset($json['success']) && $json['success'], 'upload header - success' );
if (isset($json['radix']['tank_uuid'])) $test_uuids[] = $json['radix']['tank_uuid'];
$uuid = $test_uuids[count($test_uuids)-1];

ok( $resp = $browser->http_get("upload/$uuid"), 'preview header get' );
ok( $resp = $browser->http_get("upload/$uuid/preview"), 'preview header' );
ok( $json = json_decode($resp, true), 'preview header json' );
is( $json['success'], true, 'preview header success' );

// mappings work
foreach ($json['header'] as $idx => $hdr) {
    is( $hdr['valid'], true, "preview header valid header $idx" );
}


/**********************
 * re-upload a file to an existing resource
 */
$resp = upload_file("upload/$uuid.json", 'csvfile', "$csv_dir/test_header.csv");
ok( $resp, 'preview valid re-upload' );
ok( $json = json_decode($resp, true), 'preview header re-upload - decode' );
ok( isset($json['success']) && $json['success'], 'preview header re-upload - success' );


/**********************
 * re-upload a different filename to an existing resource (fail)
 */
$resp = upload_file("upload/$uuid.json", 'csvfile', "$csv_dir/test_invalid_1.csv");
ok( $resp, 're-upload different file' );
ok( $json = json_decode($resp, true), 're-upload different file - decode' );
ok( isset($json['success']) && !$json['success'], 're-upload different file - unsuccess' );



// cleanup
$q = Doctrine_Query::create()->from('Tank')->whereIn('tank_uuid', $test_uuids);
$to_delete = $q->execute();
foreach ($to_delete as $rec) {
    $rec->delete();
}


?>
